GSP-005
Hello Kubernetes
2017년 10월 19일 목요일
오전 9:45
링크: https://google.qwiklabs.com/focuses/7011
참고 유튜브: https://goo.gl/3ezwCV
당신이 개발한
코드를 Kubernetes 위에 복제해서 돌려보자
그런데 Kubernetes는 Google Container Engine 위에서
돌거다
- 우리가 사용할 코드는 Hello World.js 앱이다
아래 다이어그램이
전체 조망도이다.
두고두고 살펴보자
* node = VM 한대
라고 생각하자

- 오픈소스 프로젝트이다. www.kubernetes.io
- 다양한 환경에서 동작한다
- laptop에서 multi-node clusters 까지
- public clouds에서 on-premise deployment 까지
- virtual machine 에서 bare metal (http://www.ciokorea.com/news/35402)
까지
- 매니지드 환경을 사용해서
설치 등등은 바로 넘어가는 거다
- 매니지드 환경은 Google Container Engine 을 사용할거다
- 이것은 Compute Engine 위에 Google-hosted version의 Kubernetes 가 설치되어 있다
1) Node.js 서버
만들고
- server.js 만들고
- 서버 돌려본다음 종료
2) Docker Container image 만들고
- Dockerfile 만들고 (from 은 Cloud 의
docker hub 에서 가져온다?)
- 빌드하고 런하고 종료한다
- 이미지를 registry 에 push
3) Container cluster 만들고
- 웹콘솔에서 만들어봄
4) Kubernetes pod를 만들고
5) 나의 서비스를 scale up!
Google Cloud Shell 에서 server.js 파일을 다음과 같이 만들자
|
var http = require('http'); var handleRequest = function(request, response) { response.writeHead(200); response.end("Hello World!"); } var www = http.createServer(handleRequest); |
|
그리고 서버를
실행시키자
- preview on port 8080 을 선택하면 볼 수 있다.
|
node server.js |
|
Cloud Shell 에서 Ctrl-c 를 눌러서 서버 중지
1) Dockerfile 은
우리가 만들 Docker image 의 설계도랄 수 있겠다.
- 나중에 이렇게 만들어줘! 하고 주면 되는거다.
2) Docker Container Image는 기존의 image 에서 확장이 가능하다.
- node image를
가져와서
- 그 위에 우리의 server.js 만 덧붙여 올릴거다.
Dockerfile 을 아래와 같이 만들자
|
1. 기존에 GCP의
Docker hub 에 있는 node:6.9.2 라는 도커이미지를 2. 8080 포트를 expose 한
상태에서 3. server.js 를 복사해 붙이겠다. 점(.)은 현재 디렉토리를 의미하는 것 같다. 4. 그리고 node.js 서버를
동작시키는 명령을 실행하라 - node server.js |
- PROJECT_ID 에는
진짜 내 프로젝트 아이디를 넣어야겠지?
- 도커이미지의 이름은
hello-node:v1 버전 1이라는 의미구만
- gcr.io 도 중요하다.
- Google Container Registry 라는 도커 이미지를 넣어두는 공간
- Google Cloud Storage 에서 gs:// 라고
prefix 해주던 것과 유사한듯
|
질문! 여기서 gcr.io로 시작하는 것은 무얼 의미하는가? us.gcr.io 라면 Registry 위치가 미국, 없으면 디폴트로 미국인듯 유럽이나
아시아로 선택할 수도 있나보다 Registry 라면 나중에 push를 또하는건 뭐지? PROJECT_ID 부분은
옵션으로 보인다. 아무 이름이나 가능한듯 아무래도
프로젝트 아이디를 넣으면 낸중에 알아보기 편할듯 마지막으로 -t 는 tag,
점(.)은 Dockerfile의 위치를 의미한다
|
|
docker build -t gcr.io/PROJECT_ID/hello-node:v1 .ㄷ |
|
빌드되면 난수들이
나올 것이다. 그러면 완성
- Dockerfile 내용이
순서대로 실행되는게 보인다
- 중간 임시 파일들이
생성되고 삭제된다
![shed-zephyr-17æ21 docker bui Id
Sending bui Id context to C:ocker daemon Bg. CGk8
step 1/4 : node:a.g.2
a.g.2: FL] Il ing from library/node
-t gcr. io/pol ished-zephyr-1 7Eæl/hel 0-node
753æ2cd7æa:
871 asa3b7æs:
01 1
I f04fe713flb:
Pull complete
Pull complete
Pull complete
Pull complete
Pull complete
Pull complete
Pull complete
Digest: lg40f44S&e4bd33fbdc34deg4a5e04.3
Status: Downloaded newer image for node :a.g.2
faaadb4aafgb
step 2/4 :
Running in
IZ74bdaceaeO
Removing intermediate container
Step 3/4 : CDP/ server. js
Remov ing intermed iate container SEEccbBbad51
Step 4/4 : node server. js
Running in c3b7æaseb73
f4ScSlafeæs
Remov ing intermediate container c.i7.3g&b7.3
Successfully built f4&51afeBE
Successfully tagged gcr io/pol i shed-zephyr-17æ21 'hel lo-node:vl](GSP-005%20Hello%20Kubernetes.files/image004.jpg)
이제는 run
-d, --detach=false 라고 하여 Detached, daemon 모드라고 하며 컨테이너가 백그라운드로 실행됨
-p, --pubilsh=[] 라고 하여 <호스트포트>:<컨테이너포트> 를 의미한다
![]()
이 자체로
도커 이미지가 Running !
![]()
결과를 보는
세 가지 방법
1) Shell 의 Preview on port 8080 선택

2) curl 또는 wget 사용
- culr http://localhost:8080
- 결과는
![]()
1) 그냥 날로 node.js 서버를 실행시키거나
2) 도커 이미지로 실행시키는
방법을 배웠다.
1) PROJECT_ID를
안쓰고 그냥 아무 이름이나 써봤다
- 만들어지긴
하는데 나중에 push 할때 안된다.
- 아마도 프로젝트 하위로 container registry 가 있기에 그런가보다
2) ./docker_test 라는 폴더를 만들고 거기에 Dockerfile을 만든다음에 node:8.7.0 을 베이스로 이미지를 만들어봤다.
- ./docker_test 폴더로 server.js 파일 복사했고
- 빌드시에 폴더를 명시했다
실습수 docker images --all 로 이미지들을 살펴보았다
![shed-zephy r-
—al
R+CSITCAV
gcr io/gcp_test2/he 0-node
I qa321 :
$ docker images
gcr io/po shed-zephyr-17æ21 'hel
gcr io/gcp_test/hel lo-node
lo-node
mone>
VI
mone>
VI
VI
mone>
mone>
B. 7.0
a.g.2
b01aceab93æ
Il f6fdld14C8
1274bd3JeaeO
faaadb4aaf%
TED
7 minutes ago
7 minutes ago
B minutes ago
Z] minutes ago
Z] minutes ago
Z] minutes ago
Z] minutes ago
g days ago
10 months ago](GSP-005%20Hello%20Kubernetes.files/image014.jpg)
|
|
docker ps 라고 치면 컨테이너 정보들이 나온다 |
|
|
- docker stop <CONTAINER
ID> 를 치면 멈춘다 - 리턴값은 컨테이너 아이디이다 |
Google Container Registry https://cloud.google.com/container-registry/
- 도커 이미지를 저장해두는
개인 공간이다.
- 따라서 개인의 Project 에서 접근이 가능하다
집어넣기
![]()
몇 분 걸리며
아래와 같이 나온다
|
The push refers to a repository [gcr.io/qwiklabs-gcp-6h281a111f098/hello-node] ba6ca48af64e: Pushed 381c97ba7dc3: Pushed 604c78617f34: Pushed fa18e5ffd316: Pushed 0a5e2b2ddeaa: Pushed 53c779688d06: Pushed 60a0858edcd5: Pushed b6ca02dfe5e6: Pushed v1: digest: sha256:8a9349a355c8e06a48a1e8906652b9259bba6d594097f115060acca8e3e941a2 size: 2002 |
|
웹콘솔의 Tools >> Container Registry 에서 볼 수 있다.
- 퀵랩실습과 내계정으로
한 실습이 섞여 캡처했으니 프로젝트명 바뀌는건 양해를
![Google Cloud Platform
Container Registry
Images
guild triggers
guild history
My Project •
Images
C REFRESH
gcrio / polished-zephyr-176321 / hello-node
Filter by name or tag
Name
[ ] 3d04e6C41494
Tags
VI](GSP-005%20Hello%20Kubernetes.files/image022.jpg)
이제 프로젝트
어디에서나 접근이 가능한 도커 이미지가 준비되었다.
= Kubernetes 가
접근해서 오케스트레이션 가능하다!
현재까지
- node.js 서버하나
만들어서 돌려봤고
- Dockerfile을
만들어 도커 이미지를 build한다음에 Google Container
Registry에 집어넣었다.

Container Engine cluster 를 만들자
- Cluster = Kubernetes master API + worker nodes
- Kubernetes master API는 구글이 hosting 해준다
- worker nodes = Compute Engine VM 이다.
웹콘솔에서
만들수도 있고, Google Cloud Shell 에서 만들수도 있다.
Container Engine > Container Clusters > Create a container
cluster.
1) 프로젝트 설정 제대로
했나 확인
gcloud config set project PROJECT_ID
![]()
2) 클러스터 생성
|
|
1) hello-world 라는 클러스터를 만들라 2) 노드는 두 개다. = VM 두개
만든다? 3) VM의 타입은
n1-standard-1 이고 4) zone 은 us-central1-f
이다 |
웹콘솔의 Container Engine에 가보면 생성된 것을 확인할 수 있다
1) 내 프로그램 server.js 를 container image 로 만들어서 container registry 에 넣어두었다.
- 아래 빨간색
2) Kubernetes cluster를 만들었다.
- 아래 파란색

이제 kubectl 이라는 CLI 로 이미지를 클러스터에 올려보자
- container 들을
하나의 그룹으로 묶은 것이다.
- Administration = 관리 하려고
- Networking = 내부에서
서로 통신하려고
|
|
- hello-node 라는 이름으로 deploy 하라 - 사용할 이미지는 container Registry 의 hello-node:v1 이고 - 포트는 8080 이다 * 여기서 hello-node 라는 이름은 좀 헷갈린다. hello-node-deployment 는 어떨까? * 궁금증. Kubernetes cluster 인 hello-world 는
언급 안했는데 괜찮나? 자동으로 알아서 현재 클러스터를 안다?
그렇다면 클러스터 여러 개라면? |
궁금증
때문에 두개의 cluster를 만들어보았다
- 두 개중에
두번째 클러스터랑 붙더라
![gc loud container clusters create hel 10-0 luster —num-nodes 2 -Hnachine-type nl-standard-l
Creat ing cluster hello-cluster.
Created [ht tps://contai ner.googleapis.com/vl/proj ects/pol ished-zephyr-l T.æl/zones/us-central I-f/cl usters/hel
10-0 luster].
kubeconfig entry generated for hello-cluster.
ZONE
hel 10-0 luster us-central I-f
MASTEPLVEFSION MASTEPLIP
MAHNE_TVFE NCOE_VEFSION STATLS
as. 193.114.73 nl-standard-l
1.7.a
gcloud container clusters create hel lo-cluster2 —num-nodes 2 —mach ine-type n I-standard-I
—zone us-cent ral I -f
-zone us-central I-f
Creat ing cluster hello-cluster2.. .done.
Created [https://container.googleapis.com/vl/proj ects/pol
kubeconfig entry generated for hello-cluster2.
ished-zephyr-1 7Eæl / zones/us-central I-f/cl usters/hel lo-c luster?]
za•4E
hel lo-cluster2 us-cent rall-f
MASTdR_VdRSICN MASTdR_IP
E.2æ.76.
MACHI NE_TVPE
241 n I-standard-I
NOCE-_VBRSICN NUM_NOCES STATUS
1.7.a](GSP-005%20Hello%20Kubernetes.files/image034.jpg)
웹콘솔에서
확인

deployment 는 pod를 만들고 scale 하는 좋은 방법이다
* 참고 node는 하나의 컴퓨터 = VM 이라고 보면된다. 하나의 컴퓨터 = VM 안에 여러 개의 컨테이너가 돌 수 있다.
|
|
deploy 한 것들 보는 방법 deploy 가 pod의 상위개념! |
|
|
pod 들을 보는 방법 |
|
|
관련 정보 보는 명령 |
|
|
tourbleshooting 명령 |
pod를 만들었는데 이건
아직 internal IP로만 접근할 수 있다. =
Kubernetes virtual network
이걸 바깥에서
접근하려면 Kubernetes service 로 pod를 expose 해줘야 한다
![]()
주의
1) 우리는 deployment 를 expose 했지 pod을 바로 expose 한 것이 아니다
2) 무얼 의미하냐면 deployment 가 pod 들로가는 traffic 을 챙긴다는 것이다
- 현재야 pod가 하나뿐이긴 하다만, 이후 몇 개의 복제 pod를 더 추가할거다
|
|
1) kubectl get services 명령으로 볼 수 있다 2) 위에거만 외부에 노출된 것을 알 수 있다 - AGE를 보면 위에거는
방금 명령으로 생겨난 것이라 1m 밖에 안된다. * The EXTERNAL-IP may take several minutes to
become available and visible. If the EXTERNAL-IP is missing,
wait a few minutes and try again. |
현재까지 정리
- 우리 앱을 컨테이너에
집어넣고, 쿠베르네티스로 관리하는 거 까지 봤다.
- 또 뭘 할 수 있을까?
초록색 kubectl 명령으로
- run 명령으로 registry의 이미지를 불러와서 Cluster에 집어넣었고
- expose 명령으로 EXTERNAL-IP를 생성했다. 이때 deployment를 만들때 명시한 8080포트를 이용해야만 볼 수
있다는 것 잊지말자

|
|
app을 스케일 업 하고 싶다면? 이렇게만 명령주면 4개로 복제된다 |
|
|
deployments 정보 |
|
|
1개 이던게 총 4개의 pod 가 되어버림 |
- 클러스터 생성시에 2개의 노드(=VM)를 가지겠다고 했고
- 그런 클러스터를 테스트삼아
두개 만든거다
- Scale 전후의 노드
개수는 변동이 없다.
- 노드(=VM) 안에 여러 개의 Pods (= 컨테이너라고 할까?)가 들어갈 수 있기 때문이다.

- 두 번째 만든 클러스터에 deploy 되었구나

|
|
1) Cloud Shell 에서 kubectl 로 Kubernetes Cluster로 명령 보낼 수 있다. 2) 다양한 device에서 External IP를 통해서 연결이 들어온다 - 123.45.678.9:8080 - Hello Service 에서 노드들에 나눠준다 궁금증 - node #1, node #2 와 그 안의 Hello Node Pod 간의 상관관계는 ? - 노드는 진짜 하나의
컴퓨터 개념 = VM 이라면 - Pods는 하나의
컴터안에서 도는 컨테이너 개수라고 할까? - Replication controller 는? |
여기까지 우리의 service.js 를 서비스하게 되었다.
그런데 service.js 를 bugfix하고, feature를 추가하고, refactoring 한다면?
- 업그레이드 하는 방법을
알아보자
1. 일단 앱을 수정한다
![]()
2. 수정한 앱으로 새로운 container image를 만들고, registry에 밀어넣는다 (v2로 버전업 명시)
|
|
1) . 은 현재폴더. 현재폴더에
있는 Dockerfile에 기반하여 이미지를 만들라는 것 2) 만든 이미지를
registry에 push |
replication controller 만 수정하면 된다

kube edit 명령만 치면 된다
![]()
|
# Please edit the object below. Lines beginning with a '#' will be ignored, # and an empty file will abort the edit. If an error occurs while saving this file will be # reopened with the relevant failures. # apiVersion: extensions/v1beta1 kind: Deployment metadata: annotations: deployment.kubernetes.io/revision: "1" creationTimestamp: 2016-03-24T17:55:28Z generation: 3 labels: run: hello-node name: hello-node namespace: default resourceVersion: "151017" selfLink: /apis/extensions/v1beta1/namespaces/default/deployments/hello-node uid: 981fe302-f1e9-11e5-9a78-42010af00005 spec: replicas: 4 selector: matchLabels: run: hello-node strategy: rollingUpdate: maxSurge: 1 maxUnavailable: 1 type: RollingUpdate template: metadata: creationTimestamp: null labels: run: hello-node spec: containers: - image: gcr.io/PROJECT_ID/hello-node:v1 ## Update this line ## imagePullPolicy: IfNotPresent name: hello-node ports: - containerPort: 8080 protocol: TCP resources: {} terminationMessagePath: /dev/termination-log dnsPolicy: ClusterFirst restartPolicy: Always securityContext: {} terminationGracePeriodSeconds: 30 |
4. 변경된
것으로 다시 돌리기
get 명령이지만
이걸 해줘야 deployment 가 update 된다.
실제 사용자는
어떤 인터럽트도 느끼지 않고 자연스럽게 버전업을 사용할 수 잇게 된다

Kubernetes cluster dashboard 를 접근하기 위한 설정
- 참고로 여기서 hello-world 는 클러스터 이름임

그리고 8081로 접근하면 된다

- 음… 그런데 해보는데
안된다.
- https://github.com/kubernetes/kubernetes/issues/52729


1) 일단 프록시 포트
설정
![]()
2) 내 컴퓨터의 브라우저를
열고 127.0.0.1:8081 을 열면
아래와 같이 나온ㄷ

3) 원래는 여기에 ui 만 붙인 https://goo.gl/dT99Hm
만 치면
http://127.0.0.1:8081/api/v1/namespaces/kube-system/services/kubernetes-dashboard/proxy
로
redirection 되면서 되어야 한다.
그런데 이 url 은 틀렸다. 정답은 아래!
|
- 맨 끝에 /를 넣어주거나 http://127.0.0.1:8081/api/v1/namespaces/kube-system/services/kubernetes-dashboard/proxy/ - proxy 단어 위치를
namepaces 앞으로 옮기고 맨 끝에 /를 넣어주면 된다. http://127.0.0.1:8081/api/v1/proxy/namespaces/kube-system/services/kubernetes-dashboard/ |
노드의 key/value 쌍인 labels 참고
- service의 LoadBalancer는 이 라벨로 노드들에 명령을 보낼 수 있다.
- 같은 라벨의 노드가 3개라면? 3개에 동시에 보내는 거다
- 또 다른 라벨로 명령을
보내느데 그건 또 다른 쌍으로 5개의 노드를 가리킨다면? 그 5개에만 보내는거다

Microsoft OneNote 2016에서 작성